import {useModel} from '@@/exports';
import {DownloadOutlined, PlusOutlined, UploadOutlined} from '@ant-design/icons';
import type {ActionType, ParamsType, ProColumns} from '@ant-design/pro-components';
import {EditableProTable} from '@ant-design/pro-components';
import {
  Button,
  DatePicker,
  DatePickerProps,
  Form,
  message,
  notification,
  Popconfirm,
  Space,
  Upload,
  UploadProps
} from 'antd';
import React, {useEffect, useRef, useState} from 'react';
import {listProductionLineUsingGET} from "@/services/model/productionLineController";
import {
  addAttendanceInfoUsingPOST,
  deleteAttendanceInfoUsingDELETE,
  editAttendanceInfoUsingPUT,
  listAttendanceInfoUsingGET
} from "@/services/model/dailyAttendanceController";
import dayjs from "dayjs";
import {errorConfig} from "@/requestErrorConfig";
import CustomSelect from "@/pages/components/CustomSelect";

const Attendance: React.FC = () => {
  const {initialState} = useModel('@@initialState');
  const actionRef = useRef<ActionType>();
  const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]);
  const [form] = Form.useForm();
  const [productionLineList, setProductionLineList] = useState<readonly API.ProductionLineDTO[]>([]);
  const [selectAddProductionLineValue, setSelectAddProductionLineValue] = useState('');
  const [selectSearchProductionLineValue, setSelectSearchProductionLineValue] = useState('');
  const [selectSearchDateValue, setSelectSearchDateValue] = useState<dayjs.Dayjs>();
  const [selectSearchPlanningDate, setSelectSearchPlanningDate] = useState<string>('');
  // 弹出上传信息数据
  type NotificationType = 'success' | 'info' | 'warning' | 'error';
  const [api, contextHolder] = notification.useNotification();
  const openNotification = (type: NotificationType, info: string) => {
    api[type]({
      message: "上传信息",
      description: info,
      duration: 0,
      placement: "bottomRight"
    });
  };

  useEffect(() => {
    listProductionLineUsingGET({
      commitUserId: initialState?.currentUser?.id,
    }).then((result) => {
      if (result.code === 0 && result.data) {
        setProductionLineList(result.data);
      }
    });
  }, []);
  const AddProductionCodeListSelect = () => {
    return (
      <CustomSelect name={"产线编码"}
                    selectDate={selectAddProductionLineValue}
                    setSelectData={setSelectAddProductionLineValue}
                    datalist={productionLineList.map(item => {
                      return {id: item.code, name: item.code}
                    })}/>
    );
  };
  const SearchProductionCodeListSelect = () => {
    return (
      <CustomSelect name={"产线编码"}
                    selectDate={selectSearchProductionLineValue}
                    setSelectData={setSelectSearchProductionLineValue}
                    datalist={productionLineList.map(item => {
                      return {id: item.code, name: item.code}
                    })}/>
    );
  };
  const AddProductionNameListSelect = () => {
    return (
      <CustomSelect name={"产线名称"}
                    selectDate={selectAddProductionLineValue}
                    setSelectData={setSelectAddProductionLineValue}
                    datalist={productionLineList.map(item => {
                      return {id: item.code, name: item.name}
                    })}/>
    );
  };
  const SearchProductionNameListSelect = () => {
    return (
      <CustomSelect name={"产线名称"}
                    selectDate={selectSearchProductionLineValue}
                    setSelectData={setSelectSearchProductionLineValue}
                    datalist={productionLineList.map(item => {
                      return {id: item.code, name: item.name}
                    })}/>
    );
  };
  const onSelectSearchDateChange: DatePickerProps['onChange'] = (date, dateString) => {
    setSelectSearchPlanningDate(dateString)
    if (date) {
      setSelectSearchDateValue(date)
    } else {
      setSelectSearchDateValue(undefined)
    }
  };
  const SearchDateSelect = () => {
    return <DatePicker value={selectSearchDateValue} onChange={onSelectSearchDateChange} picker="month"/>
  }

  const initDailyAttendance = async (params: ParamsType & {pageSize?: number | undefined, current?: number | undefined, keyword?: string | undefined}) => {
    const result = await listAttendanceInfoUsingGET({
      commitUserId: initialState?.currentUser?.id,
      productionLineCode: selectSearchProductionLineValue,
      attendanceDate: selectSearchPlanningDate,
      pageSize: params.pageSize,
      pageNum: params.current,
    });
    if (result.data && result.data.list) {
      result.data.list.forEach(item => {
        if (item.targetEfficiency) {
          item.targetEfficiency = Number((item.targetEfficiency * 100).toFixed(2));
        }
      })
      return {
        data: result.data.list,
        total: result.data.total,
        success: result.code === 0,
      }
    }
    return {}
  };


  const onDelete = async (id: number) => {
    const result = await deleteAttendanceInfoUsingDELETE({
      id,
      currentUserId: initialState?.currentUser?.id,
    });
    if (result.code === 0 && result.data) {
      message.success('删除成功');
      actionRef.current?.reload();
    } else {
      message.warning(result.message);
    }
  };
  const onSave = async (row: any) => {
    const currentUserId = initialState?.currentUser?.id;
    const newAttendanceInfo: API.AddAttendanceInfoQuery = {
      currentUserId,
      actualNumber: row.actualNumber,
      attendanceDate: row.attendanceDate,
      targetEfficiency: row.targetEfficiency ? Number((row.targetEfficiency * 0.01).toFixed(2)) : undefined,
      planningNumber: row.planningNumber,
      productionLineCode: selectAddProductionLineValue,
      workTime: row.workTime,
    };
    const result = await addAttendanceInfoUsingPOST(newAttendanceInfo);
    if (result.code === 0 && result.data) {
      message.success('添加成功');
    } else {
      message.warning(result.message);
    }
    actionRef.current?.reload();
  };
  const onEdit = async (row: API.AttendanceInfoDTO) => {
    const currentUserId = initialState?.currentUser?.id;
    const newAttendanceInfo: API.EditAttendanceInfoQuery = {
      currentUserId,
      id: row.id,
      actualNumber: row.actualNumber,
      attendanceDate: row.attendanceDate,
      planningNumber: row.planningNumber,
      targetEfficiency: row.targetEfficiency ? Number((row.targetEfficiency * 0.01).toFixed(2)) : undefined,
      productionLineCode: row.productionLineCode,
      workTime: row.workTime,
    };
    const result = await editAttendanceInfoUsingPUT(newAttendanceInfo);
    if (result.code === 0 && result.data) {
      message.success('修改成功');
    } else {
      message.warning(result.message);
    }
    actionRef.current?.reload();
  };

  const columns: ProColumns<API.AttendanceInfoDTO>[] = [
    {
      title: 'id',
      key: 'id',
      dataIndex: 'id',
      hideInTable: true,
      hideInSearch: true,
    },
    {
      title: '序号',
      key: 'index',
      render: (dom, entity, index) => (
        index + 1
      ),
      editable: false
    },
    {
      title: '产线编码',
      key: 'productionLineCode',
      dataIndex: 'productionLineCode',
      valueType: 'text',
      editable: (text, record: any) => {
        return record.type === "addAttendanceInfo";
      },
      renderFormItem: (_, {isEditable}) => isEditable ? <AddProductionCodeListSelect/> :
        <SearchProductionCodeListSelect/>,

    },
    {
      title: '产线名称',
      key: 'productionLineName',
      dataIndex: 'productionLineName',
      valueType: 'text',
      editable: (text, record: any) => {
        return record.type === "addAttendanceInfo";
      },
      renderFormItem: (_, {isEditable}) => isEditable ? <AddProductionNameListSelect/> : <SearchProductionNameListSelect/>,
    },
    {
      title: '出勤日期',
      key: 'attendanceDate',
      dataIndex: 'attendanceDate',
      valueType: 'date',
      renderFormItem: (_, {isEditable, defaultRender}) => isEditable ? defaultRender(_) : <SearchDateSelect/>,
    },
    {
      title: '开班时长',
      key: 'workTime',
      dataIndex: 'workTime',
      valueType: 'digit',
      hideInSearch: true,
      render: (dom, entity) => (
        <span>{entity.workTime ? entity.workTime + 'H' : '-'}</span>
      ),
    },
    {
      title: '实际出勤人数',
      key: 'actualNumber',
      dataIndex: 'actualNumber',
      valueType: 'digit',
      hideInSearch: true,
    },
    {
      title: '产线规划人数',
      key: 'planningNumber',
      dataIndex: 'planningNumber',
      valueType: 'digit',
      hideInSearch: true,
    },
    {
      title: '目标效率',
      key: 'targetEfficiency',
      dataIndex: 'targetEfficiency',
      valueType: 'percent',
      hideInSearch: true,
    },
    {
      title: '操作',
      valueType: 'option',
      render: (text, record, _, action) => [
        <a
          key="editable"
          onClick={(e) => {
            form.resetFields();
            e.stopPropagation()
            action?.startEditable?.(record.id);
          }}
        >
          编辑
        </a>,
        <Popconfirm
          key={'onDelete'}
          title="你想要删除这个日出勤数据吗"
          onConfirm={() => onDelete(record.id)}
          okText="Yes"
          cancelText="No"
        >
          <a key="deletable" onClick={(e) => e.stopPropagation()}>删除</a>
        </Popconfirm>,
      ],
    },
  ];

  const props: UploadProps = {
    withCredentials: true,
    name: 'file',
    data: {
      currentUserId: initialState?.currentUser?.id,
    },
    action: errorConfig.baseURL + '/daily/attendanceInfo/upload',
    headers: {
      authorization: 'authorization-text',
    },
    onChange(info) {
      if (info.file.status !== 'uploading') {
      }
      if (info.file.status === 'done') {
        console.log(info);
        message.success(`${info.file.name} 上传成功`);
        if (info.file.response.code === 0 && info.file.response.data) {
          actionRef.current?.reload();
          openNotification('success',info.file.response.data);
        } else {
          openNotification('warning',"提交数据无效，请检查上传文件！");
        }
      } else if (info.file.status === 'error') {
        message.error(`${info.file.name} 上传失败`);
      }
    },
  };

  return (
    <div>
      {contextHolder}
      <div style={{display: "flex", justifyContent: "space-between", marginBottom: '5px'}}>
        <Space>
          <Button
            type="primary"
            onClick={() => {
              setSelectAddProductionLineValue('');

              actionRef.current?.addEditRecord?.({
                id: (Math.random() * 1000000).toFixed(0),
                type: 'addAttendanceInfo',
              });
            }}
            icon={<PlusOutlined/>}
          >
            新增 日出勤基础数据
          </Button>
          <Button
            key="restet"
            onClick={() => {
              setSelectAddProductionLineValue('')
              form.resetFields();
            }}
          >
            重置表单
          </Button>
        </Space>
        <Space>
          <Button
            type="dashed"
            key="downloadDailyAttendance"
            icon={<DownloadOutlined/>}
            onClick={() => {
              const url = errorConfig.baseURL + '/daily/attendanceInfo/download?';
              let params = "commitUserId=" + initialState?.currentUser?.id + "&";
              if (selectSearchProductionLineValue) {
                params += "productionLineCode=" + selectSearchProductionLineValue + "&";
              }
              if (selectSearchPlanningDate) {
                params += "attendanceDate=" + selectSearchPlanningDate;
              }
              window.location.href = url + params;
            }}
          >
            导出数据
          </Button>
          <Upload {...props}>
            <Button icon={<UploadOutlined/>}>上传数据</Button>
          </Upload>
        </Space>
      </div>

      <EditableProTable<API.AttendanceInfoDTO>
        rowKey="id"
        actionRef={actionRef}
        search={{
          labelWidth: 'auto',
        }}
        scroll={{y: 'calc(100vh - 260px)'}}
        recordCreatorProps={false}
        columns={columns}
        pagination={{
          defaultPageSize: 50,
        }}
        request={(params: ParamsType & {pageSize?: number | undefined, current?: number | undefined, keyword?: string | undefined} ) => initDailyAttendance(params)}
        onReset={() => {
          setSelectSearchProductionLineValue('')
          setSelectSearchPlanningDate('')
          setSelectSearchDateValue(undefined)
        }}
        editable={{
          form,
          editableKeys,
          onSave: async (key, row: any) => {
            if (row.type === 'addAttendanceInfo') {
              await onSave(row);
            } else {
              await onEdit(row);
            }
          },
          onChange: setEditableRowKeys,
          actionRender: (row, config, dom) => [dom.save, dom.cancel],
        }}
      />
    </div>
  );
};

export default Attendance;
